package main

import (
	"github.com/gin-gonic/gin"
	"github.com/golang/protobuf/proto"
	"time"
	"net/http"
	"log"
	"os"
	"os/signal"
	"context"
	"fmt"
	"bidding"
)

type Login struct {
	User     string `form:"user" json:"user" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}

func main() {
	router := gin.New()
	router.GET("/", func(c *gin.Context) {
		time.Sleep(3 * time.Second)
		c.String(http.StatusOK, "Welcome Gin Server")
	})
	router.GET("/:name", func(c *gin.Context) {
		name := c.Param("name")
		res := fmt.Sprintf("Hello %s", name)
		fmt.Println(res)
		c.String(http.StatusOK, res)
	})
	router.POST("/form", func(c *gin.Context) {
		tp := c.DefaultPostForm("type", "alert")//可设置默认值
		msg := c.PostForm("msg")
		title := c.PostForm("title")
		res := fmt.Sprintf("type is %s, msg is %s, title is %s", tp, msg, title)
		fmt.Println(res)
		c.String(http.StatusOK, res)
	})
	router.POST("/login", func(c *gin.Context) {
		var u Login
		if c.Bind(&u) == nil {
			res := fmt.Sprintf("user is %s, password is %s", u.User, u.Password)
			fmt.Println(res)
			c.String(http.StatusOK, res)
		}
	})
	router.POST("/raw", func(c *gin.Context) {
		data, err := c.GetRawData()
		if err == nil {
			res := string(data)
			fmt.Println(res)
			c.String(http.StatusOK, res)
		}
	})
	router.POST("/proto", func(c *gin.Context) {
		data, err := c.GetRawData()
		if err == nil {
			var req bidding.BidRequest
			err = proto.Unmarshal(data, &req)
			if err != nil{
				log.Fatalln("UnMashal data error:", err)
			} else {
				res := fmt.Sprintf("requestId %s, command %s", req.RequestId, req.Command)
				fmt.Println(res)
				var resp bidding.BidResponse
				resp.Status = 666
				resp.Msg = res
				stb, err := proto.Marshal(&resp)
				if err == nil {
					c.Data(http.StatusOK, "application/octet-stream", stb)
				} else {
					c.String(http.StatusInternalServerError, "marshar err")
				}
			}
		}
	})

	srv := &http.Server{
		Addr:    ":8000",
		Handler: router,
	}

	go func() {
		// service connections
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s\n", err)
		}
	}()

	// Wait for interrupt signal to gracefully shutdown the server with
	// a timeout of 5 seconds.
	quit := make(chan os.Signal)
	signal.Notify(quit, os.Interrupt)
	<-quit
	log.Println("Shutdown Server ...")

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		log.Fatal("Server Shutdown:", err)
	}
	log.Println("Server exiting")
}